package com.lntea.netty.secureChat;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.ssl.SslHandler;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.net.InetAddress;
import java.net.InetSocketAddress;

/**
 * Title: SecureChatServerHandler.java<br>
 * Description:  <br>
 * Copyright: Copyright (c) 2015<br>
 * Company: 北京云杉世界信息技术有限公司<br>
 *
 * @author lichao
 * @date 2019/11/13 14:39
 */
public class SecureChatServerHandler extends SimpleChannelInboundHandler<String> {

    static final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    /**
     * 建立安全连接后，加入channel组
     *
     * @author lichao
     * @date 2019/11/13 14:43
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ctx.pipeline().get(SslHandler.class)
                .handshakeFuture().addListener((future) -> {
            InetSocketAddress ipSocket = (InetSocketAddress) ctx.channel().remoteAddress();
            System.out.println("新的客户端连接 " + ipSocket.getAddress() + ":" + ipSocket.getPort());
            // 向新的客户端连接发送欢迎信息
            ctx.write("Welcome to " + InetAddress.getLocalHost().getHostName() + "!\r\n");
            ctx.write("Your session is protected by " + ctx.pipeline().get(SslHandler.class).engine().getSession().getCipherSuite() + " cipher suite.\r\n");
            ctx.flush();

            // 新用户连接，通知群里其他用户
            notifyGroup(ctx, "Welcome " + "[" + ctx.channel().remoteAddress() + "] " + " to enter the room!");
            channels.add(ctx.channel());
        });
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        // 当前channel消息单独显示
        // 其他channel信息通知组播
        notifyGroup(ctx, "[" + ctx.channel().remoteAddress() + "] " + msg);

        if ("bye".equals(msg.toLowerCase())) {
            ctx.close();
        }
    }

    /**
     * 组播通知共用方法
     * @author lichao
     * @date 2019/11/13 15:02
     */
    private void notifyGroup(ChannelHandlerContext ctx, String msg) {
        for (Channel channel : channels) {
            if (ctx.channel() != channel) {
                channel.writeAndFlush(msg + "\n");
            } else {
                channel.writeAndFlush("[You] " + msg + "\n");
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}
